/*
 *
 *  * Copyright:  2018 smarabbit studio.
 *  *
 *  *  Licensed under the Confluent Community License; you may not use this file
 *  *  except in compliance with the License.  You may obtain a copy of the License at
 *  *
 *  *  http://www.confluent.io/confluent-community-license
 *  *
 *  *  Unless required by applicable law or agreed to in writing, software
 *  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  *  specific language governing permissions and limitations under the License.
 *  *
 *  *  @作   者： 黄开晖 (117227773@qq.com)
 *  *  @日   期:    ${DATE}
 *
 */

/**
 * 
 */
package com.massyframework.beanskin.runtime.service.instrument;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.massyframework.beanskin.service.secure.SecureCapacity;

/**
 * {@link ClassFileTransformerCollection},类增强器组
 * 
 * @author huangkh
 */
class ClassFileTransformerCollection implements ClassFileTransformer {

	private static final Logger LOG = LoggerFactory.getLogger(ClassFileTransformerCollection.class);
	private final Set<ClassFileTransformer> transformers;

	/**
	 * 创建新实例
	 */
	public ClassFileTransformerCollection() {
		this.transformers = new CopyOnWriteArraySet<>();	
	}

	@Override
	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
			ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

		if (loader != null) {
			if (loader instanceof SecureCapacity) { // 如果是加密类，则跳过
				 String name = className.replace("/", ".");
				if (((SecureCapacity) loader).isDecryptClass(name)) {
					if (LOG.isDebugEnabled()){
						LOG.debug("found transform decrpted class:" + className + ", skip.");
					}
					return null;
				}
			}
		}

		boolean transformed = false;
		byte[] result = classfileBuffer;
		for (ClassFileTransformer transformer : transformers) {
			byte[] tmp = transformer.transform(loader, className, classBeingRedefined, protectionDomain, result);
			if (tmp != null) {
				result = tmp;
				transformed = true;
			}
		}
		return transformed ? result : null;
	}

	/**
	 * 添加类转换器
	 * 
	 * @param transformer {@link ClassFileTransformer}
	 */
	public void addClassFileTransformer(ClassFileTransformer transformer) {
		if (transformer != null) {
			this.transformers.add(transformer);
		}
	}

	/**
	 * 移除类转换器
	 * 
	 * @param transformer {@link ClassFileTransformer}
	 */
	public boolean removeClassFileTransformer(ClassFileTransformer transformer) {
		if (transformer != null) {
			return this.transformers.remove(transformer);
		}
		return false;
	}

	/**
	 * 清除所有类转换器
	 */
	public void clean() {
		this.transformers.clear();
	}
}
